using System;
using System.Drawing;
using System.Collections.Generic;


namespace Alexus.DDrawScene.PaintJobs
{
	public abstract class PaintJob
	{
		DateTime _createdTime;
		TimeSpan _timeToLive = TimeSpan.MaxValue;


		protected PaintJob() {
			_createdTime = DateTime.Now;
		}

		public abstract RectangleF Bounds { get;}
		public abstract void DrawOn(ObjectDrawer target);
		public DateTime createdDate { get { return _createdTime; } }
		public TimeSpan timeToLive {
			get { return _timeToLive; }
			set { _timeToLive = value; }
		}
		public bool HasTTL { get { return (_timeToLive != TimeSpan.MaxValue); } }
		public bool IsAlive {
			get {
				if(!HasTTL) return true;
				DateTime TimeOfDeath = _createdTime.Add(_timeToLive);
				return TimeOfDeath.CompareTo(DateTime.Now) > 0;
			}
		}



	}

	public class RectanglePaintJob : PaintJob
	{
		RectangleF rect;
		Color? color;

		public Color? Color {
			get { return color; }
			set { color = value; }
		}


		public RectanglePaintJob(RectangleF rect) : this(rect, null) { }
		public RectanglePaintJob(RectangleF rect, Color? color) {
			this.rect = rect;
			this.color = color;
		}

		public override RectangleF Bounds {
			get { return rect; }
		}

		public override void DrawOn(ObjectDrawer target) {
			if (color != null) target.PushDrawColor(color.Value);
			target.DrawRect(rect);
			if (color != null) target.PopDrawColor();
		}
	}

	public class PolygonPaintJob : PaintJob
	{
		Polygon _pol;

		Color? color = null;

		public Color? Color {
			get { return color; }
			set { color = value; }
		}

		public PolygonPaintJob(Polygon pol) {
			_pol = pol;
		}

		public override RectangleF Bounds {
			get { return _pol.GetBounds(); }
		}

		public override void DrawOn(ObjectDrawer target) {
			if (_pol._tops.Count < 2) return;
			if (color != null) target.PushDrawColor(color.Value);
			LinkedListNode<PointF> pt = _pol._tops.First;
			while (pt.Next != null) {
				target.DrawLine(pt.Value, pt.Next.Value);
				pt = pt.Next;
			}
			target.DrawLine(_pol._tops.Last.Value, _pol._tops.First.Value);
			if (color != null) target.PushDrawColor(color.Value);
		}
	}

	public class PJGliph : PaintJob
	{
		Bitmap picture;
		RectangleF pos;

		public PJGliph(Bitmap picture, RectangleF position) {
			this.picture = picture;
			pos = position;
		}

		public override RectangleF Bounds {
			get { return pos; }
		}

		public override void DrawOn(ObjectDrawer target) {
			if (picture == null) return;
			target.DrawPicture(picture, pos);

		}
	}
}